package com.sgq.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sgq.dao.RoleMapper;
import com.sgq.dao.UserMapper;
import com.sgq.entity.Permission;
import com.sgq.dao.PermissionMapper;
import com.sgq.entity.User;
import com.sgq.service.PermissionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sgq.utils.MenuTree;
import com.sgq.vo.PermissionQueryVo;
import com.sgq.vo.RolePermissionVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author sgq
 * @since 2024-09-13
 */
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private UserMapper userMapper;

    @Override
    public IPage<Permission> findPage(PermissionQueryVo permissionQueryVo) {
        //传递一个page对象 =》 当前页  数据条数大小
        System.out.println("permissionQueryVo = " + permissionQueryVo);
        Long pageNum = permissionQueryVo.getPageNum();
        Long pageSize = permissionQueryVo.getPageSize();
        IPage<Permission> page = new Page<>(pageNum,pageSize);
        //条件按名字
        LambdaQueryWrapper<Permission> queryWrapper = new LambdaQueryWrapper<>();
        //判断条件是否为空 "username"
        queryWrapper.like(!ObjectUtils.isEmpty(permissionQueryVo.getName()), Permission::getName, permissionQueryVo.getName());

        IPage<Permission> iPage = this.baseMapper.selectPage(page, queryWrapper);
        return iPage;
    }

    @Override
    public List<Permission> findPermissionListByUserId(Long userId) {
        return this.baseMapper.selectPermissionListByUserId(userId);
    }

    /**
     * 根据条件查询权限列表（用于主页展示）
     * @param permissionQueryVo
     * @return
     */
    @Override
    public List<Permission> findPermissionList(PermissionQueryVo permissionQueryVo) {

        LambdaQueryWrapper<Permission> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.orderByAsc(Permission::getOrderNum);
        //按顺序把所有权限获取
        List<Permission> permissions = this.baseMapper.selectList(queryWrapper);
        //把查询的权限交个MenuTree构建菜单树
        List<Permission> permissionTree = MenuTree.makeMenuTree(permissions, 0L);
        //返回菜单树
        return permissionTree;
    }

    /**
     * 查询所有权限构成的权限树（用于新增权限，修改权限）
     * @return
     */
    @Override
    public List<Permission> findParentPermissionList() {
         //构造查询条件
        LambdaQueryWrapper<Permission> queryWrapper = new LambdaQueryWrapper<>();
        //按顺序查询
        queryWrapper.orderByAsc(Permission::getOrderNum);
        //按顺序查询
        List<Permission> permissions = this.baseMapper.selectList(queryWrapper);
        //创建了一个新的对象
        Permission permission = new Permission();

        permission.setId(0L);

        permission.setParentId(-1L);

        permission.setLabel("根菜单");

        permissions.add(permission);

        List<Permission> permissionTree = MenuTree.makeMenuTree(permissions, -1L);

        return permissionTree;
    }

    /**
     * 根据id判断是否有子权限
     * @param id
     * @return
     */
    @Override
    public boolean hasChildrenInPermission(Long id) {
        LambdaQueryWrapper<Permission> queryWrapper = new LambdaQueryWrapper<>();
        //查询是否有以id为父ParentId的权限
        queryWrapper.eq(Permission::getParentId,id);
        Long count = this.baseMapper.selectCount(queryWrapper);
        return count > 0 ;
    }

    /**
     * 核对当前菜单是否分配了角色
     * @param id
     * @return
     */
    @Override
    public boolean checkPermissionUsed(Long id) {
        int count = roleMapper.checkRoleIsUse(id);
        return count > 0;
    }

    /**
     * 根据权限code判断权限是否存在（是否是重复的）
     * @param permission  权限
     *
     * @return
     */
    @Override
    public boolean checkPermissionCode(Permission permission) {
        LambdaQueryWrapper<Permission> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Permission::getCode,permission.getCode());
        Long id = permission.getId();
        //如果是修改权限，则排除自己
        if(id != null){
            queryWrapper.ne(Permission::getId,id);
        }
        Long count = this.baseMapper.selectCount(queryWrapper);
        return count > 0 ;
    }

    @Override
    public RolePermissionVo findPermissionTree(Long userId, Long roleId) {
        //1.查询当前用户信息
        User user = userMapper.selectById(userId);
        List<Permission> list = null;
        //2.判断当前用户角色，如果是管理员，则查询所有权限；如果不是管理员，则只查询自己所拥有的的权限
        if(!ObjectUtils.isEmpty(user.getIsAdmin()) && user.getIsAdmin() == 1){
            //查询所有权限
            list = this.baseMapper.selectList(null);
        }else{
            //根据用户ID查询权限
            list = this.baseMapper.selectPermissionListByUserId(userId);
        }
        //3.组装成树数据
        List<Permission> permissionList = MenuTree.makeMenuTree(list, 0L);
        //4.查询要分配角色的原有权限
        List<Permission> rolePermissions = baseMapper.findPermissionListByRoleId(roleId);
        //5.过滤掉用户空权限并且获取权限id
        List<Long> userPermissionIds = list.stream().filter(permission -> {
            if (!ObjectUtils.isEmpty(permission) && !ObjectUtils.isEmpty(permission.getId())) {
                return true;
            }
            return false;
        }).map(permission -> permission.getId()).collect(Collectors.toList());
        //6.过滤掉角色空权限并且获取权限id
        List<Long> rolePermissionIds = rolePermissions.stream().filter(permission -> {
            if (!ObjectUtils.isEmpty(permission) && !ObjectUtils.isEmpty(permission.getId())) {
                return true;
            }
            return false;
        }).map(permission -> permission.getId()).collect(Collectors.toList());
        //7.获取当前用户与角色重叠的权限
        userPermissionIds.retainAll(rolePermissionIds);
        //8.封装数据
        RolePermissionVo vo = new RolePermissionVo();
        vo.setPermissionList(permissionList);
        vo.setCheckList(userPermissionIds.toArray());
        return vo;
    }
}
